Technote TE 19 | February 1990 |
Changes since February 1990: Added a note about the changes in TextEdit
for System Software 6.0.5, documented the low-memory global TESysJust,
clarified information about text direction and _TESetJust,
discussed problems with the SetWordBreak routine along with a solution
to work around it, and described the differences in dialog text item behavior.
In addition to all the features of earlier versions, TextEdit 3.0 now allows you to take advantage of the Script Manager's handling of systems with more than one script system installed. TextEdit uses the Script Manager to support such systems and now exhibits the correct behavior for editing and displaying text in multiple styles and different scripts. Multiple scripts can even exist on a single line due to TextEdit's use of the Script Manager. The new version of TextEdit in 6.0.5:
* handles mixed-directional text
* synchronizes keyboards and fonts
* handles double-byte characters
* determines word boundaries and line breaks
* provides outline highlighting in the background
* buffers text for performance improvements
* permits left justification in right-to-left directional scripts
* customizes word breaking
* customizes measuring
Refer to the TextEdit chapter in Inside Macintosh, Volume VI, for detailed documentation on TextEdit 3.0.
The LineStarts array is a field in a TextEdit record that contains the offset position of the first character of each line. This array has the following boundary conditions:
* It is a zero-based array.
* The last entry in the array must have the same value as teLength.
* The maximum number of entries is 16,000.
To determine the length of a line you can use the information contained in the lineStarts array and nLines. For example, if you want to determine the length of line n, subtract the value contained in entry n of the array from the value in the entry (n+1):
lengthOfLineN := myTE^^.lineStarts[n+1] - myTE^^.lineStarts[n];
The terminating condition for this measurement is when n = nLines + 1. It is important not to change the information contained in the array.
TESysJust is a low-memory global that specifies the system justification. The default value of this global is normally based on the system script. It is -1 when a system's default line direction is right to left, and 0 for a default left-to-right line direction. Applications may change the value using the Script Manager routine SetSysJust; however, these applications should save the current value before using it and restore it before exiting the application or processing a MultiFinder suspend event. The current value may be obtained using the Script Manager routine GetSysJust.
The original TextEdit documentation introduced _TESetJust with three possible choices for justification: teJustLeft (0), teJustCenter (1), and teJustRight (-1). These choices are appropriate for script systems that are read from left to right. However, in script systems that are read from right to left, text is incorrectly displayed as left justified in dialog boxes and in other areas of applications where users cannot explicitly set the justification. To fix this problem, the behavior of teJustLeft has changed to match the line direction of the system in use, which is the value stored in TESysJust. Another constant has been added to allow an application to force left justification: teForceLeft (-2). This constant has been available for some time, but it has not been documented until now. If your application does not allow the user to change the justification, then it should use teJustLeft; if it does, then it should use teForceLeft for left justification.
If the redraw parameter used in _TESetStyle is FALSE, line breaks, line heights, and line ascents are not recalculated. Therefore a succeeding call to a routine using any of this information does not reflect the new style information. For example, a call to _TEGetHeight (which returns a total height between two specified lines) uses the line height set previous to the _TESetStyle call. A call to _TECalText is necessary to update this information. If redraw is TRUE, the current style information is reflected. This behavior also holds for the redraw parameter in _TEReplaceStyle.
There is currently space reserved for four documented hooks in the TEDispatchRec: TEEolHook, TEWidthHook, TEDrawHook and TEHitTestHook. The space beyond these hooks is reserved, and any attempt to use this private area results in corrupted TextEdit data.
A problem exists in one of TextEdit's advanced procedures, SetWordBreak. The current glue code does not preserve the state of the registers correctly; however, the solution is fairly simple. Instead of calling SetWordBreak and passing a pointer to your custom word break routine, pass the pointer to your external glue which should call your custom word break routine. Following is the glue code that correctly handles the registers:
WordBreakProc PROC EXPORT IMPORT MYWORDBREAK ;Must be uppercase here MOVEM.L D1-D2/A1,-(SP) CLR.W -(SP) ;Space for result MOVE.L A0,-(SP) ;Move the ptr to stack MOVE.W D0,-(SP) ;Move the charpos to Stack JSR MYWORDBREAK MOVE.W (SP)+,D0 ;Set Z bit MOVEM.L (SP)+,D1-D2/A1 RTS ENDP
An external declaration is also necessary:
FUNCTION WordBreakProc( text: Ptr; charPos: INTEGER ) : BOOLEAN; EXTERNAL;
as is the function itself. One thing that should be noted is that it is not really necessary to have MyWordBreak boolean, but rather to have the Z bit set properly. The result of the function should be zero when you do not want a break; otherwise, a non-zero value indicates a break is desired.
FUNCTION MyWordBreak( text : Ptr; charPos : INTEGER ) : INTEGER; { Your word break code here. }
For more information, refer to the TextEdit chapter of Inside Macintosh, Volume I-380.
The Dialog Manager depends on TextEdit to display text in dialog boxes. For an editable text field, the Dialog Manager simply calls _TEUpdate. Before making this call, it may double the width of the rectangle to contain the text if the height of the rectangle is sufficient for only one line and the line direction specified by TESysJust is left to right. In this case, the Dialog Manager extends the rectangle on the right. Note, however, this does not occur when your line direction is right to left.
For static text items, _TextBox is used instead. When the display
rectangle is not large enough. _TextBox clips the text to the size of
the specified rectangle. To avoid the clipping problem, simply make the
display rectangle larger. If your dialog box contains both static and editable
text items, the difference in the text handling may appear inconsistent.
Further Reference:
Main | Page One | What's New | Apple Computer, Inc. | Find It | Contact Us | Help